package org.opens.lambda.stream;

import com.google.common.io.Resources;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class CreateStream {

    /**
     * 功能:
     *      Collection接口的实现了天然实现了stream方法, 可以对集合类型直接使用stream过去流对象.
     * 注意:
     *      1. list的底层给予有序的数组, stream可以保证这个顺序;
     */
    @Test
    public void test1() {
        List<String> strings = Arrays.asList("sdas", "adf", "asfa", "fgdge", "wasd");
        Stream<String> stream = strings.stream();
    }

    /**
     * 功能:
     *      使用Stream的静态方法of来获取Stream流对象.
     */
    @Test
    public void test2() {
        Stream<String> stream = Stream.of("sdas", "adf", "asfa", "fgdge", "wasd");

    }

    /**
     * 功能:
     *      通过Arrays的stream方法来将数组转换为Stream流对象.
     */
    @Test
    public void test3() {
        Arrays.stream(new String[]{"sdas", "adf", "asfa", "fgdge", "wasd"});
    }

    /**
     * 功能:
     *      将文件的内容读取为Stream流对象.
     * 注意:
     *      1. 每一行为一个单独的Strnig对象.
     *      2. 不能使用相对路径.
     *      3. System.getProperty("user.dir");的输出为当前项目的项目路径;
     */
    @Test
    public void test4() {
        //Path path = Paths.get("E:\\idea-project\\springboot-test\\src\\test\\java\\org\\opens\\lambda\\stream\\SimpleStream.java");
        Path path = Paths.get(System.getProperty("user.dir") + "\\src\\test\\java\\org\\opens\\lambda\\stream\\SimpleStream.java");
        try {
            Stream<String> lines = Files.lines(path);
            lines.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 功能:
     *      创建一个无限的Stream流对象.
     * 说明:
     *      1. iterate方法有两个参数:
     *          - 第一个参数表示这个流的初始值;
     *          - 第二个参数表示这个流迭代时的迭代规则;
     * 注意:
     *      1. 由于这个流是无限的, 所以一般需要搭配limit来实现.
     */
    @Test
    public void test5() {
        Stream<Integer> stream = Stream.iterate(0, n -> n + 2);
        stream.limit(15).forEach(System.out::println);
    }

    /**
     * 功能:
     *      通过generated方式创建一个无限的流对象.
     * 说明:
     *      1. 与iterate不同的是: iterate的变化需要开发者干预, 它接受的参数是一个UnaryOperator类型的函数式接口; 但是generate接受的参数是一个Supplier函数式接口, 也就是说产生的值是不依赖外界的.
     */
    @Test
    public void test6() {
        Stream<Double> stream = Stream.generate(Math::random);
        stream.limit(15).forEach(System.out::println);
    }

    /**
     * 功能:
     *      创建IntStream.
     */
    @Test
    public void test7() {
        Random random = new Random();
        IntStream intStream = IntStream.generate(random::nextInt);
        intStream.limit(10).forEach(System.out::println);
    }

}
